package com.company;


import static com.company.CodeInputAndScan.*;

public class Lex {
    static String[] keywordsTable ={"if","int","for","while","do","return","break","continue"};
    static String[] state_sets={"start","inID","inNum","LINE","EA","GE","+","-","*","/",",",";","(",")","{","}"};

    static int code=-1;//用于查找保留字
    static String token="";
    static String state="start";//设置初始状态为start
    static char ch;

    public static void main(String[] args){
        inputOriginCode();
        readChar();
        parsing();
    }

    public static void parsing(){
        while(inState_sets(state)){
            if(isLetter(ch)){state="inID";token=new Character(ch).toString();ch=readChar();}
            if(isDigit(ch)){state="inNum";token=new Character(ch).toString();ch=readChar();}
            switch (state){
                case "start":{
                    switch (ch) {
                        case '<':{state="LINE";token=new Character(ch).toString();ch=readChar();break;}
                        case '=':{state="EA";token=new Character(ch).toString();ch=readChar();break;}
                        case '>':{state="GE";token=new Character(ch).toString();ch=readChar();break;}
                        case '+':{state="+";token=new Character(ch).toString();break;}
                        case '-':{state="-";token=new Character(ch).toString();break;}
                        case '*':{state="*";token=new Character(ch).toString();break;}
                        case '/':{state="/";token=new Character(ch).toString();break;}
                        case ',':{state=",";token=new Character(ch).toString();break;}
                        case ';':{state=";";token=new Character(ch).toString();break;}
                        case '(':{state="(";token=new Character(ch).toString();break;}
                        case ')':{state=")";token=new Character(ch).toString();break;}
                        case '{':{state="{";token=new Character(ch).toString();break;}
                        case '}':{state="}";token=new Character(ch).toString();break;}
                        default:{ch=readChar();break;}//过滤掉无用的符号
                    }
                    break;
                }

                case "inID":{
                    while ((isLetter(ch) || isDigit(ch))) {
                        token=token+ch;
                        code=lookup(token,keywordsTable);
                        ch=readChar();
                        if(code !=-1){
                            System.out.println("("+1+","+token+")");
                            afterPrint();
                            break;
                        }
                    }
                    if(code==-1) {
                        System.out.println("("+2+","+token+")");
                        afterPrint();
                    }
                    code=-1;
                    stateChange(ch);
                    break;
                }

                case "inNum":{
                    while(isDigit(ch)){
                        token=token+ch;
                        ch=readChar();
                    }
                    System.out.println("("+3+","+token+")");
                    afterPrint();
                    stateChange(ch);
                    break;
                }

                case "LINE" :{
                    if(ch=='>') System.out.println("("+4+",<>)");
                    if(ch=='=') System.out.println("("+4+",<=)");
                    else System.out.println("("+4+",<)");
                    ch=readChar();
                    afterPrint();
                    stateChange(ch);
                    break;
                }

                case "EA":{
                    if(ch=='=') System.out.println("("+4+",==");
                    else System.out.println("("+4+",=)");
                    ch=readChar();
                    afterPrint();
                    stateChange(ch);
                    break;
                }

                case "GE":{
                    if(ch=='=') System.out.println("("+4+",>=");
                    else System.out.println("("+4+",>)");
                    ch=readChar();
                    afterPrint();
                    stateChange(ch);
                    break;
                }

                case"+":{
                    System.out.println("("+4+",+)");
                    ch=readChar();
                    afterPrint();
                    stateChange(ch);
                    break;
                }

                case"-":{
                    System.out.println("("+4+",-)");
                    ch=readChar();
                    afterPrint();
                    stateChange(ch);
                    break;
                }

                case"*":{
                    System.out.println("("+4+",*)");
                    ch=readChar();
                    afterPrint();
                    stateChange(ch);
                    break;
                }

                case"/":{
                    System.out.println("("+4+",/)");
                    ch=readChar();
                    afterPrint();
                    stateChange(ch);
                    break;
                }

                case",":{
                    System.out.println("("+5+",,)");
                    ch=readChar();
                    afterPrint();
                    stateChange(ch);
                    break;
                }

                case";":{
                    System.out.println("("+5+",;)");
                    ch=readChar();
                    afterPrint();
                    stateChange(ch);
                    break;
                }

                case"(":{
                    System.out.println("("+5+",()");
                    ch=readChar();
                    afterPrint();
                    stateChange(ch);
                    break;
                }

                case")":{
                    System.out.println("("+5+",))");
                    ch=readChar();
                    afterPrint();
                    stateChange(ch);
                    break;
                }

                case"{":{
                    System.out.println("("+5+",{)");
                    ch=readChar();
                    afterPrint();
                    stateChange(ch);
                    break;
                }

                case"}":{
                    System.out.println("("+5+",})");
                    ch=readChar();
                    afterPrint();
                    stateChange(ch);
                    break;
                }

                default:  break;

            }
        }
    }
    public static boolean isLetter(char ch){
        return (ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z');
    }

    public static boolean isDigit(char ch){
        return (ch>='0'&&ch<='9');
    }

    public static void reportError(){
        System.out.println("Error");
    }

    public static int lookup(String token, String[] keywordsTable){
        for(int i=0;i<keywordsTable.length;i++){
            if(keywordsTable[i].equals(token)) return i;
        }
        return -1;
    }

    public static char readChar(){
        if(point<origincode.length())
            return ch=getChar(origincode);
        else
            System.out.println("词法分析完成!");
        return '#';

    }

    public static void stateChange(char ch){
        if(inState_sets(new Character(ch).toString()))
            state=new Character(ch).toString();
        else if(ch=='#') state=new Character('#').toString();
        else state="start";
    }

    public static boolean inState_sets(String state){
        return (state_sets[0].equals(state)||state_sets[1].equals(state)||state_sets[2].equals(state)||
                state_sets[3].equals(state)||state_sets[4].equals(state)||state_sets[5].equals(state)||
                state_sets[6].equals(state)||state_sets[7].equals(state)||state_sets[8].equals(state)||
                state_sets[9].equals(state)||state_sets[10].equals(state)||state_sets[11].equals(state)||
                state_sets[12].equals(state)||state_sets[13].equals(state)||state_sets[14].equals(state)||
                state_sets[15].equals(state));
    }
    public static void afterPrint(){
        if(isLetter(ch)||isDigit(ch)||inState_sets(new Character(ch).toString()))
            token=new Character(ch).toString();
        else if(new Character(ch).toString().equals(" ")){ch=readChar();token="";}
        else if(ch!='#')reportError();
    }

}
